/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    i2c_dma_test.c
 *  @brief   i2c dma testcase source file
 *  @version v1.0
 *  @date    10. Sep. 2023
 ****************************************************************/

#include "printf.h"
#include "hal_api.h"
#include "common.h"
#include "io.h"
#include "bits.h"
#include <string.h>

#define I2C_TX_DMA_CHAN    0
#define I2C_RX_DMA_CHAN    1

#define EEPROM_DEVICE_ADDR        0x57
#define BUF_LEN                   128
#define EEPROM_ADDR               0x00
#define TEST_TIMES                8
#define TEST_DATA                 0xA5
#define PAGE_NUMS                 8
#define PAGE_LEN                  64

#define I2C_CMD_WRITE_REQ         0
#define I2C_CMD_READ_REQ          BIT(8)
#define I2C_CMD_STOP              BIT(9)


static __align(64) uint32_t dma_read_buf[BUF_LEN];
static __align(64) uint16_t dma_write_buf[BUF_LEN];

static int32_t eeprom_write_page_data55(I2c_Id i2c, I2c_Addr_t addr)
{
	uint32_t i;

	dma_write_buf[0] = I2C_CMD_WRITE_REQ | (uint8_t)((addr >> 8) & 0xFF);
	dma_write_buf[1] = I2C_CMD_WRITE_REQ | (uint8_t)(addr & 0xFF);

	for (i = 2; i < 65; i++) {
		dma_write_buf[i] = I2C_CMD_WRITE_REQ | TEST_DATA;
	}
	dma_write_buf[65] = I2C_CMD_STOP | I2C_CMD_WRITE_REQ | TEST_DATA;

	return Hal_I2c_Dma_Write(i2c, dma_write_buf, 66);

}

static int32_t eeprom_read_dma_data(I2c_Id i2c, I2c_Addr_t addr)
{
	uint32_t i;

	dma_write_buf[0] = I2C_CMD_WRITE_REQ | (uint8_t)((addr >> 8) & 0xFF);
	dma_write_buf[1] = I2C_CMD_WRITE_REQ | (uint8_t)(addr & 0xFF);
	for (i = 2; i < 65; i++) {
		dma_write_buf[i] = I2C_CMD_READ_REQ;
	}
	dma_write_buf[65] = I2C_CMD_READ_REQ | I2C_CMD_STOP;

	Hal_I2c_Dma_Read(i2c, dma_write_buf, 66, dma_read_buf, 64);

	return 0;
}

int32_t test_i2c_dma(void)
{
	uint8_t i;
	uint8_t page;
	int32_t ret;
	printf("\r\n[I2C DMA]: TEST START\r\n");
	ret = Hal_I2c_Tar_Add_Cfg(I2C_ID_0, EEPROM_DEVICE_ADDR);
	if (ret) {
		printf("[I2C DMA]: set i2c device addr err\r\n");
		return ret;
	}
	ret =  Hal_I2c_Request_Dma_Chan(I2C_ID_0, I2C_TX_DMA_CHAN, I2C_RX_DMA_CHAN);
	if (ret) {
		printf("[I2C DMA]: i2c req dma chan err\r\n");
		return ret;
	}

	for (page = 0; page < PAGE_NUMS; page++) {
		ret =  eeprom_write_page_data55(I2C_ID_0, EEPROM_ADDR + page * PAGE_LEN);
		if (ret) {
			printf("[I2C DMA]: i2c dma write data err\r\n");
			return ret;
		}

		Hal_Cnt_DelayMs(500);

		ret = eeprom_read_dma_data(I2C_ID_0, EEPROM_ADDR + page * PAGE_LEN);
		if (ret) {
			printf("[I2C DMA]: i2c dma read data err\r\n");
			return ret;
		}

		for (i = 0; i < 64; i++) {
			if ((dma_read_buf[i] & 0xFF) != TEST_DATA) {
				printf("[I2C DMA]: i2c dma transfer data err\r\n");
				return -1;
			}
		}
	}

	printf("[I2C DMA]: i2c dma transfer data test ok\r\n");
	printf("[I2C DMA]: TEST END\r\n");

	return 0;
}

